package com.robotserver.orders.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.robotserver.orders.common.DateFormatUtil;
import com.robotserver.orders.common.DateUtil;
import com.robotserver.orders.common.Math;
import com.robotserver.orders.entity.AlimmTokens;
import com.robotserver.orders.entity.TbOrders;
import com.robotserver.orders.enums.BizStatus;
import com.robotserver.orders.mapper.AlimmTokensMapper;
import com.robotserver.orders.mapper.TbOrdersMapper;
import com.robotserver.orders.service.TbPayOrderSyncService;
import com.robotserver.orders.vo.TbkOrderTimeVO;
import com.taobao.api.TaobaoClient;
import com.taobao.api.request.TbkScOrderDetailsGetRequest;
import com.taobao.api.response.TbkScOrderDetailsGetResponse;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Service
public class TbPayOrderSyncServiceImpl implements TbPayOrderSyncService {

    private static Logger logger = LoggerFactory.getLogger(TbPayOrderSyncServiceImpl.class);

    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private TbOrdersMapper tbOrdersMapper;
    @Autowired
    private AlimmTokensMapper alimmTokensMapper;

    private static long pagesize = 100;
    private static long querytype = 2; // 付款时间
    private static long tkstatus = 12; // 状态为付款订单
    private static long jumptype = 1;  // 向前翻页

    @Override
    public void syncAlimmUnitOrder(List<TbkOrderTimeVO> tbkOrderTimeVOList, AlimmTokens alimmTokens, TaobaoClient client,Long orderScene) {
        for (TbkOrderTimeVO tbkOrderTimeVO:tbkOrderTimeVOList){
            syncTimeUnitOrder(tbkOrderTimeVO,alimmTokens,client,null,1l, orderScene);
//            try {
//                Thread.sleep(1); //线程停止1毫秒
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
        }
    }

    @Override
    public void syncTimeUnitOrder(TbkOrderTimeVO tbkOrderTime, AlimmTokens alimmTokens, TaobaoClient client,String positionindex,Long pageNo,Long orderScene) {
        try {
            TbkScOrderDetailsGetRequest req = new TbkScOrderDetailsGetRequest();
            logger.info("-----远程拉取所有联盟订单任务--------"+alimmTokens.getAccessToken()+"::"+alimmTokens.getUserName()+"::"+tbkOrderTime.getBeginTime()+"::"+tbkOrderTime.getEndTime());
            req.setQueryType(querytype);
            if (StringUtils.isNotBlank(positionindex)){
                req.setPositionIndex(positionindex);
            }
            req.setPageSize(pagesize);
            req.setTkStatus(tkstatus);
            req.setStartTime(tbkOrderTime.getBeginTime());
            req.setEndTime(tbkOrderTime.getEndTime());
            req.setJumpType(jumptype);
            req.setPageNo(pageNo);
            req.setOrderScene(orderScene);

            TbkScOrderDetailsGetResponse rsp = client.execute(req, alimmTokens.getAccessToken());

            // 处理入库
            if (rsp.getData()!=null){
                //logger.info(alimmTokens.getUserName()+"::"+tbkOrderTime.getBeginTime()+"::"+tbkOrderTime.getEndTime()+"::"+positionindex+"::"+pageNo+">>"+rsp.getBody());
                ordersAdd(rsp.getData().getResults(),alimmTokens);

                if (rsp.getData().getHasNext()){
                    pageNo = pageNo+1;
                    syncTimeUnitOrder(tbkOrderTime,alimmTokens,client,rsp.getData().getPositionIndex(),pageNo,orderScene);
                }else {
                    // 修改心跳
                    if (alimmTokens.getId()!=null){
                        int now = DateUtil.getNowTime();
                        alimmTokensMapper.updateHeartbeat(alimmTokens.getId(),now);
                    }
                }
            }else {
                // 修改心跳
                if (alimmTokens.getId()!=null){
                    int now = DateUtil.getNowTime();
                    alimmTokensMapper.updateHeartbeat(alimmTokens.getId(),now);
                }
            }
        } catch (Exception e) {
            logger.error("sync tb pay order err:",e);
        }
    }

    @Transactional
    @Override
    public void ordersAdd(List<TbkScOrderDetailsGetResponse.PublisherOrderDto> orders,AlimmTokens alimmTokens) {
        int now = DateUtil.getNowTime();
        if (orders==null || orders.size()==0){
            return ;
        }
        for (TbkScOrderDetailsGetResponse.PublisherOrderDto order:orders){
            // 查询订单是否存在
            TbOrders tbOrder = tbOrdersMapper.getByOrderNo(order.getTradeParentId(),order.getTradeId());
            if (tbOrder!=null){
                try {
                    boolean update = false;
                    if (tbOrder.getSpecialId()==null && order.getSpecialId()!=null){
                        tbOrder.setSpecialId(order.getSpecialId());
                        update = true;
                    }
                    if (tbOrder.getRelationId()==null && order.getRelationId()!=null){
                        tbOrder.setRelationId(order.getRelationId());
                        update = true;
                    }

                    if (tbOrder.getAlipayTotalPrice()==null || tbOrder.getAlipayTotalPrice().intValue()!=Math.currencyFormatToF(order.getAlipayTotalPrice())){
                        tbOrder.setAlipayTotalPrice(Math.currencyFormatToF(order.getAlipayTotalPrice()));
                        update = true;
                    }
                    int tkcreatetime = DateUtil.getStrTime(order.getTkCreateTime());
                    if (tbOrder.getTkCreateTime()==null || tbOrder.getTkCreateTime().intValue()!=tkcreatetime){
                        tbOrder.setTkCreateTime(tkcreatetime);
                        update = true;
                    }

                    int tkpaidtime = DateUtil.getStrTime(order.getTkPaidTime());
                    if (tbOrder.getTkPaidTime()==null || tbOrder.getTkPaidTime().intValue()!=tkpaidtime){
                        tbOrder.setTkPaidTime(tkpaidtime);
                        update = true;
                    }
                    if (update){
                        tbOrdersMapper.updateSpId(tbOrder);
                    }
                } catch (Exception e) {
                    logger.error("err:{}",e);
                }
                continue;
            }else {
                try{
                    // 添加
                    logger.info("add tb pay order:parentId: {},childId: {},tkstatus:{}",new Object[]{order.getTradeParentId(),order.getTradeId(),order.getTkStatus()});
                    String orderStr = JSONObject.toJSONString(order);
                    logger.info("add tb pay order:orderStr: {}:",orderStr);
                    TbOrders newOrder = new TbOrders();
                    newOrder.setId(IdWorker.getId());
                    newOrder.setCreateTime(now);
                    newOrder.setUpdateTime(now);
                    newOrder.setAdzoneId(order.getAdzoneId());
                    newOrder.setAdzoneName(order.getAdzoneName());
                    newOrder.setAlimamaRate(Math.strToDouble(order.getAlimamaRate()));
                    newOrder.setAlimamaShareFee(Math.currencyFormatToF(order.getAlimamaShareFee()));
                    newOrder.setAlimmUserId(String.valueOf(alimmTokens.getUserId()));
                    newOrder.setAlimmUserName(alimmTokens.getUserName());
                    newOrder.setAlipayTotalPrice(Math.currencyFormatToF(order.getAlipayTotalPrice()));
                    newOrder.setAppKey(order.getAppKey());

                    //modify by 2021-03-10 18:00 by liuqi
                    newOrder.setAlscId(order.getAlscId());
                    newOrder.setAlscPid(order.getAlscPid());
                    newOrder.setLxRid(order.getLxRid());
                    newOrder.setIsLx(order.getIsLx());
                    newOrder.setMarketingType(order.getMarketingType());
                    Date modifyTimeDate = DateFormatUtil.StringToDateFormat(order.getModifiedTime(),"yyyy-MM-dd HH:mm:ss");
                    Integer modifyTime = DateUtil.getTime(modifyTimeDate);
                    newOrder.setModifiedTime(modifyTime);

                    newOrder.setBizStatus(BizStatus.pay.getValue());
                    newOrder.setClickTime(DateUtil.getStrTime(order.getClickTime()));
                    newOrder.setDepositPrice(Math.currencyFormatToF(order.getDepositPrice()));
                    newOrder.setFlowSource(order.getFlowSource());
                    newOrder.setIncomeRate(Math.strToDouble(order.getIncomeRate()));
                    newOrder.setItemCategoryName(order.getItemCategoryName());
                    newOrder.setItemId(order.getItemId());
                    newOrder.setItemImg(order.getItemImg());
                    newOrder.setItemLink(order.getItemLink());
                    newOrder.setItemNum(order.getItemNum());
                    newOrder.setItemPrice(Math.currencyFormatToF(order.getItemPrice()));
                    newOrder.setItemTitle(order.getItemTitle());

                    newOrder.setOrderType(order.getOrderType());
                    newOrder.setPayPrice(Math.currencyFormatToF(order.getPayPrice()));
                    newOrder.setPubId(order.getPubId());
                    newOrder.setPubShareFee(Math.currencyFormatToF(order.getPubShareFee()));
                    newOrder.setPubSharePreFee(Math.currencyFormatToF(order.getPubSharePreFee()));
                    newOrder.setPubShareRate(Math.strToDouble(order.getPubShareRate()));
                    newOrder.setRefundTag((int) order.getRefundTag().longValue());
                    newOrder.setRelationId(order.getRelationId());
                    String sellerNick = order.getSellerNick();
                    if(StringUtils.isNotBlank(sellerNick)){
                        newOrder.setSellerNick(sellerNick.length() > 32 ? sellerNick.substring(0,30): sellerNick);
                    }
                    newOrder.setSellerShopTitle(order.getSellerShopTitle());
                    newOrder.setSiteId(order.getSiteId());
                    newOrder.setSiteName(order.getSiteName());
                    newOrder.setSpecialId(order.getSpecialId());
                    newOrder.setSubsidyRate(Math.strToDouble(order.getSubsidyRate()));
                    newOrder.setSubsidyFee(Math.currencyFormatToF(order.getSubsidyFee()));
                    newOrder.setSubsidyType(order.getSubsidyType());
                    newOrder.setTbDepositTime(DateUtil.getStrTime(order.getTbDepositTime()));
                    newOrder.setTbPaidTime(DateUtil.getStrTime(order.getTbPaidTime()));
                    newOrder.setTerminalType(order.getTerminalType());
                    newOrder.setTkCommissionFeeForMediaPlatform(Math.currencyFormatToF(order.getTkCommissionFeeForMediaPlatform()));
                    newOrder.setTkCommissionPreFeeForMediaPlatform(Math.currencyFormatToF(order.getTkCommissionPreFeeForMediaPlatform()));
                    newOrder.setTkCommissionRateForMediaPlatform(Math.strToDouble(order.getTkCommissionRateForMediaPlatform()));
                    newOrder.setTkCreateTime(DateUtil.getStrTime(order.getTkCreateTime()));
                    newOrder.setTkEarningTime(DateUtil.getStrTime(order.getTkEarningTime()));
                    newOrder.setTkOrderRole(order.getTkOrderRole());
                    newOrder.setTkPaidTime(DateUtil.getStrTime(order.getTkPaidTime()));
                    newOrder.setTradeId(order.getTradeId());
                    newOrder.setTradeParentId(order.getTradeParentId());
                    newOrder.setTkTotalRate(Math.strToDouble(order.getTkTotalRate()));
                    newOrder.setTkStatus((int)order.getTkStatus().longValue());
                    newOrder.setTotalCommissionRate(Math.strToDouble(order.getTotalCommissionRate()));
                    newOrder.setTotalCommissionFee(Math.currencyFormatToF(order.getTotalCommissionFee()));
                    newOrder.setTkDepositTime(DateUtil.getStrTime(order.getTkDepositTime()));
                    newOrder.setPid("mm_"+order.getPubId()+"_"+order.getSiteId()+"_"+order.getAdzoneId());
                    try {
                        tbOrdersMapper.add(newOrder);
                    } catch (Exception e) {
                        logger.error("add err:{}",e);
                        tbOrder = tbOrdersMapper.getByOrderNo(order.getTradeParentId(),order.getTradeId());
                        if (tbOrder != null){
                            boolean updateFlag = false;
                            if(tbOrder.getSpecialId()==null && order.getSpecialId()!=null){
                                tbOrder.setSpecialId(order.getSpecialId());
                                updateFlag = true;
                            }
                            if(tbOrder.getRelationId()==null && order.getRelationId()!=null){
                                tbOrder.setRelationId(order.getRelationId());
                                updateFlag = true;
                            }
                            if(updateFlag){
                                tbOrdersMapper.updateSpId(tbOrder);
                            }
                        }
                    }
                } catch (Exception e) {
                    logger.error("err:{}",e);
                }

            }
        }
    }

    @Async("taskExecutor")
    @Override
    public void threadSyncOrder(List<TbkOrderTimeVO> tbkOrderTimeVOList, List<AlimmTokens> alimmTokens, TaobaoClient client,String lockName,Long orderScene) {
        threadLockSyncOrder(tbkOrderTimeVOList,alimmTokens,client,lockName,orderScene);
    }

    @Override
    public void threadLockSyncOrder(List<TbkOrderTimeVO> tbkOrderTimeVOList, List<AlimmTokens> alimmTokens, TaobaoClient client,String lockName,Long orderScene) {

        if (alimmTokens.size()>0){
            AlimmTokens token = null;
            RLock lock = null;
            try {
                lock = redissonClient.getLock(lockName);
                lock.lock();
                token = alimmTokens.get(0);
                // 删除对象
                alimmTokens.remove(token);

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (lock!=null){
                    lock.unlock();
                }
            }

            if (token!=null){
                logger.info(lockName+"::token>"+token.getUserId());
                syncAlimmUnitOrder(tbkOrderTimeVOList,token,client,orderScene);
                threadLockSyncOrder(tbkOrderTimeVOList,alimmTokens,client,lockName,orderScene);
            }
        }
    }

    @Async("taskExecutor")
    @Override
    public void threadSyncOrder_consumer(List<TbkOrderTimeVO> tbkOrderTimeVOList, AlimmTokens alimmTokens, TaobaoClient client, Long orderScene) {
        syncAlimmUnitOrder(tbkOrderTimeVOList,alimmTokens,client,orderScene);
    }

}
